﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using DcsGauges.Gui.Rendering;
using DcsGauges.DataStructures;
using DcsGauges.Gui.Controls;
using DcsGauges.Gui.Views;
using DcsGauges.Input.Events;
using DcsGauges.Input.Processors;
using Microsoft.Xna.Framework;
using DcsGauges.Gui.Views.Concrete;
using Microsoft.Xna.Framework.Graphics;
using System.Diagnostics;

namespace DcsGauges.Gui
{
    class ViewSwitcher : View
    {
        private const string                    BUTTON_BACKGROUND       = "Textures/Controls/Button/ButtonBackgroundGrey";

        private Button                          leftButton              = null;
        private Button                          upButton                = null;
        private Button                          rightButton             = null;
        private Button                          downButton              = null;
        private ClickInputProcessor             inputProcessor          = null;
        private bool                            navButtonVisible        = false;


        private AdiHsiView                      adiHsiView              = null;
        public AdiHsiView                       AdiHsiView
        {
            get { return this.adiHsiView; }
        }

        private EnginesView                     enginesView             = null;
        public EnginesView                      EnginesView
        {
            get { return this.enginesView; }
        }

        private LightsControlView               lightsControlView       = null;
        public LightsControlView                LightsControlView
        {
            get { return this.lightsControlView; }
        }

        private CautionView                     cautionView             = null;
        public CautionView                      CautionView
        {
            get { return this.cautionView; }
        }

        private TestingView                     testingView             = null;
        public TestingView                      TestingView
        {
            get { return this.testingView; }
        }

        public ElectricalAndOxygenRegulatorView ElectricalAndOxygenView { get; private set; }
        public EnvironmentOxygenTestView        EnvironemntOxygenTest   { get; private set; }

        private View                            currentView             = null;

        private Dictionary<View, ViewChoice>    viewNavigation  = new Dictionary<View,ViewChoice>();


        public ViewSwitcher(GraphicsDevice device)
        {
            this.upButton               = new Button(this,
                new URect(new ULoc(0.2f, 0.0f), new USize(0.6f, 0.1f)), 
                TextureManager.GetTexture(BUTTON_BACKGROUND), 
                "Up");
            this.leftButton             = new Button(this,
                new URect(new ULoc(0.0f, 0.2f), new USize(0.1f, 0.6f)), 
                TextureManager.GetTexture(BUTTON_BACKGROUND),
                "Left", Button.ButtonOrientation.Vertical);
            this.rightButton            = new Button(this,
                new URect(new ULoc(0.9f, 0.2f), new USize(0.1f, 0.6f)), 
                TextureManager.GetTexture(BUTTON_BACKGROUND), 
                "Right", Button.ButtonOrientation.Vertical);
            this.downButton             = new Button(this,
                new URect(new ULoc(0.2f, 0.9f), new USize(0.6f, 0.1f)), 
                TextureManager.GetTexture(BUTTON_BACKGROUND),
                "Down");

            this.inputProcessor                 = new ClickInputProcessor(this, MouseEvent.MouseButtons.Right);
            this.inputProcessor.Click           += OnInputProcessorClick;

            this.adiHsiView                     = new AdiHsiView(device);
            this.enginesView                    = new EnginesView();
            this.testingView                    = new TestingView(device);
            this.ElectricalAndOxygenView        = new ElectricalAndOxygenRegulatorView();
            this.EnvironemntOxygenTest          = new EnvironmentOxygenTestView();
            this.lightsControlView              = new LightsControlView();
            this.cautionView                    = new CautionView();

            this.viewNavigation.Add(this.adiHsiView,                new ViewChoice(this.testingView, null, this.enginesView, null));
            this.viewNavigation.Add(this.enginesView,               new ViewChoice(this.adiHsiView, null, this.ElectricalAndOxygenView, null));
            this.viewNavigation.Add(this.ElectricalAndOxygenView,   new ViewChoice(this.CautionView, null, null, this.EnvironemntOxygenTest));
            this.viewNavigation.Add(this.EnvironemntOxygenTest,     new ViewChoice(null, this.ElectricalAndOxygenView, null, this.lightsControlView));
            this.viewNavigation.Add(this.lightsControlView,         new ViewChoice(null, this.EnvironemntOxygenTest, null, null));

            this.leftButton.Click               += OnLeftButtonClick;
            this.upButton.Click                 += OnUpButtonClick;
            this.rightButton.Click              += OnRightButtonClick;
            this.downButton.Click               += OnDownButtonClick;

            this.currentView = this.lightsControlView;
        }

        void OnUpButtonClick(object sender, EventArgs e)
        {
            ViewChoice vc = this.GetViewChoice();
            Debug.Assert(vc.UpView != null, "Up button shouldn't be visible when there is no up view in the current view choice");
            this.currentView = vc.UpView;
        }

        void OnDownButtonClick(object sender, EventArgs e)
        {
            ViewChoice vc = this.GetViewChoice();
            Debug.Assert(vc.DownView != null, "Down button shouldn't be visible when there is no down view in the current view choice");
            this.currentView = vc.DownView;
        }

        void OnLeftButtonClick(object sender, EventArgs e)
        {
            ViewChoice vc = this.GetViewChoice();
            Debug.Assert(vc.LeftView != null, "Left button shouldn't be visible when there is no left view in the current view choice");
            this.currentView = vc.LeftView;
        }

        void OnRightButtonClick(object sender, EventArgs e)
        {
            ViewChoice vc = this.GetViewChoice();
            Debug.Assert(vc.RightView != null, "Right button shouldn't be visible when there is no up view in the current view choice");
            this.currentView = vc.RightView;
        }

        private ViewChoice GetViewChoice()
        {
            ViewChoice vc = null;
            this.viewNavigation.TryGetValue(this.currentView, out vc);
            Debug.Assert(vc != null);
            return vc;
        }

        void OnInputProcessorClick(object sender, EventArgs e)
        {
            this.navButtonVisible = !this.navButtonVisible;
        }

        public override void Render(Microsoft.Xna.Framework.Graphics.SpriteBatch spriteBatch, Microsoft.Xna.Framework.Graphics.GraphicsDevice device, Microsoft.Xna.Framework.Rectangle parentRect, float globalZIndex)
        {
            Rectangle rect = this.CalcViewportRect(parentRect);

            if (this.navButtonVisible)
            {
                ViewChoice vc               = null;
                this.viewNavigation.TryGetValue(this.currentView, out vc);
                if (vc != null)
                {
                    if(vc.UpView    != null)        this.upButton.Render(spriteBatch, device, rect, globalZIndex);
                    if(vc.LeftView  != null)        this.leftButton.Render(spriteBatch, device, rect, globalZIndex);
                    if(vc.RightView != null)        this.rightButton.Render(spriteBatch, device, rect, globalZIndex);
                    if(vc.DownView  != null)        this.downButton.Render(spriteBatch, device, rect, globalZIndex);
                }
            }

            if(this.currentView != null)
            {
                this.currentView.Render(spriteBatch, device, rect, this.NextBackIndex(globalZIndex, 5));
            }
        }

        public override void InjectMouseEvent(MouseEvent evt, Microsoft.Xna.Framework.GameTime gt)
        {
            if(this.navButtonVisible == true)
            {
                this.leftButton.InjectMouseEvent(evt, gt);
                this.upButton.InjectMouseEvent(evt, gt);
                this.rightButton.InjectMouseEvent(evt, gt);
                this.downButton.InjectMouseEvent(evt, gt);
            }

            if(evt.WasHandeled == false && this.currentView != null)
                this.currentView.InjectMouseEvent(evt, gt);

            this.inputProcessor.InjectMouseEvent(evt, gt);
            //base.InjectMouseEvent(evt, gt);
        }
    }
}
